/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */

package org.openmrs.module.clinicalsummary.evaluator.velocity;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.log.Log4JLogChute;
import org.openmrs.Cohort;
import org.openmrs.Patient;
import org.openmrs.api.context.Context;
import org.openmrs.module.clinicalsummary.configuration.Configuration;
import org.openmrs.module.clinicalsummary.evaluator.Evaluator;
import org.openmrs.module.clinicalsummary.evaluator.EvaluatorUtils;

public class VelocityEvaluator implements Evaluator {

	private static final Log log = LogFactory.getLog(VelocityEvaluator.class);

	private VelocityEngine engine;

	public VelocityEvaluator() throws Exception {
		engine = new VelocityEngine();
		engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, Log4JLogChute.class.getName());
		engine.setProperty("runtime.log.logsystem.log4j.logger", VelocityEvaluator.class.getName());
		engine.init();
	}

	/**
	 * Evaluate cohort of patients and then generate the summary sheet data
	 */
	public void evaluate(final Cohort cohort, final Configuration configuration) {

		VelocityConfiguration velocityConfiguration = (VelocityConfiguration) configuration;

		VelocityContext context = new VelocityContext();
		// put the default function that comes with the module
		context.put("fn", new VelocityUtils());
		for (String functionKey : velocityConfiguration.getFunctions().keySet())
			context.put(functionKey, velocityConfiguration.getFunctions().get(functionKey));

		File outputDirectory = EvaluatorUtils.getOutputDirectory(velocityConfiguration.getOutputDirectory());

		for (Integer patientId : cohort.getMemberIds()) {
			try {
				Patient patient = Context.getPatientService().getPatient(patientId);

				context.put("patient", patient);
				context.put("patientId", patientId);

				String xmlFilename = EvaluatorUtils.getXmlFilename(String.valueOf(patientId));
				File xmlFile = new File(outputDirectory, xmlFilename);

				BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(xmlFile));
				engine.evaluate(context, bufferedWriter, VelocityEvaluator.class.getName(), velocityConfiguration.getTemplate());

				bufferedWriter.close();
			} catch (IOException e) {
				log.error("Exception thrown when processing patient: " + patientId, e);
			}
		}
	}
}
